package com.yanqu.road.server.manager.activity.jinli;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.jinli.CrossJinLiData;
import com.yanqu.road.entity.activity.jinli.CrossJinLiUserData;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.log.LogJinLiAdd;
import com.yanqu.road.entity.log.LogJinLiLucky;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.activity.CrossJinLiBusiness;
import com.yanqu.road.logic.bussiness.log.LogBussiness;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.JinLiProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 锦鲤签活动数据
 */
public class CrossJinLiActivity {

    // mallId,幸运签数据
    private Map<Integer, CrossJinLiData> jinLiDataMap = new ConcurrentHashMap<>();


    // mallId,userId,用户幸运签数据
    private Map<Integer, Map<Long, CrossJinLiUserData>> userDataMap = new ConcurrentHashMap<>();

    private RandomHelper randomHelper = new RandomHelper();

    private ActivityInfo activityInfo;

    /**
     * 商品配置，有多少档位，锦鲤就有多少档位
     */
    private Map<Integer, MallInfo> mallInfoMap = new ConcurrentHashMap<>();

    /**
     * 礼包锁
     */
    private final Map<Integer, Object> mallLockMap = new ConcurrentHashMap<>();


    public void reloadConfig(ActivityInfo activityInfo) {
        // 刷一下活动
        this.activityInfo = activityInfo;
        // 加载一下商品的配置
//        mallInfoMap = ActivityBussiness.getActivityMallInfoMap(Collections.singletonList(activityInfo.getActivityId())).getOrDefault(activityInfo.getActivityId(), new ConcurrentHashMap<>());
        Map<Integer, MallInfo> tempMallInfoMap = ActivityBussiness.getActivityMallInfoMap(Collections.singletonList(activityInfo.getActivityId())).getOrDefault(activityInfo.getActivityId(), new ConcurrentHashMap<>());
        List<Integer> removeOldList = new ArrayList<>();
        for (MallInfo mallInfo : mallInfoMap.values()) {
            if (mallInfo.getActivityId() == activityInfo.getActivityId()) {
                removeOldList.add(mallInfo.getMallId());
            }
        }
        for (Integer mallId : removeOldList) {
            mallInfoMap.remove(mallId);
        }

        for (MallInfo mallInfo : tempMallInfoMap.values()) {
            if (mallInfo.getActivityId() == activityInfo.getActivityId()) {
                mallInfoMap.put(mallInfo.getMallId(), mallInfo);
            }
        }
    }

    /**
     * 获取玩家锁
     */
    private Object getMallLock(int mallId) {
        if (!mallLockMap.containsKey(mallId)) {
            synchronized (mallLockMap) {
                if (!mallLockMap.containsKey(mallId)) {
                    mallLockMap.put(mallId, new Object());
                }
            }
        }
        return mallLockMap.get(mallId);
    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public CrossJinLiActivity(ActivityInfo activityInfo) {
        if (activityInfo == null) {
            return;
        }
        // 不在展示期内不处理
        if (!ActivityHelper.activityInShowTime(activityInfo)) {
            return;
        }
        this.activityInfo = activityInfo;
        // 加载一下商品的配置
//        mallInfoMap = ActivityBussiness.getActivityMallInfoMap(Collections.singletonList(activityInfo.getActivityId())).getOrDefault(activityInfo.getActivityId(), new ConcurrentHashMap<>());
        Map<Integer, MallInfo> tempMallInfoMap = ActivityBussiness.getActivityMallInfoMap(Collections.singletonList(activityInfo.getActivityId())).getOrDefault(activityInfo.getActivityId(), new ConcurrentHashMap<>());
        List<Integer> removeOldList = new ArrayList<>();
        for (MallInfo mallInfo : mallInfoMap.values()) {
            if (mallInfo.getActivityId() == activityInfo.getActivityId()) {
                removeOldList.add(mallInfo.getMallId());
            }
        }
        for (Integer mallId : removeOldList) {
            mallInfoMap.remove(mallId);
        }

        for (MallInfo mallInfo : tempMallInfoMap.values()) {
            if (mallInfo.getActivityId() == activityInfo.getActivityId()) {
                mallInfoMap.put(mallInfo.getMallId(), mallInfo);
            }
        }

        // 加载一下数据
        jinLiDataMap = CrossJinLiBusiness.getCrossJinLiDataMap(activityInfo.getActivityId());
        userDataMap = CrossJinLiBusiness.getCrossJinLiUserDataMap(activityInfo.getActivityId());
    }

    public void save() {
        //  数据入库
        for (Map<Long, CrossJinLiUserData> map : userDataMap.values()) {
            for (CrossJinLiUserData jinLiUserData : map.values()) {
                if (jinLiUserData.isInsertOption()) {
                    CrossJinLiBusiness.addCrossJinLiUserData(jinLiUserData);
                } else if (jinLiUserData.isUpdateOption()) {
                    CrossJinLiBusiness.updateCrossJinLiUserData(jinLiUserData);
                }
            }
        }
        for (CrossJinLiData jinLiData : jinLiDataMap.values()) {
            if (jinLiData.isInsertOption()) {
                CrossJinLiBusiness.addCrossJinLiData(jinLiData);
            } else if (jinLiData.isUpdateOption()) {
                CrossJinLiBusiness.updateCrossJinLiData(jinLiData);
            }
        }

    }

    /**
     * 添加锦鲤
     */
    public void addJinLi(long serverId, long userId, int mallId) {
        // 有没有档位
        MallInfo mallInfo = mallInfoMap.get(mallId);
        if (mallInfo == null) {
            return;
        }
        // 随机一个幸运签,这里加个锁
        synchronized (getMallLock(mallId)) {
            Map<Long, CrossJinLiUserData> listMap = userDataMap.getOrDefault(mallId, new ConcurrentHashMap<>());
            if (listMap.containsKey(userId)) {
                // 已有了，不处理
                return;
            }
            // 获取当前的幸运数字
            CrossJinLiData jinLiData = getJinLiData(mallId);
            CrossJinLiUserData jinLiUserData = new CrossJinLiUserData();
            jinLiUserData.setActivityId(activityInfo.getActivityId());
            jinLiUserData.setUserId(userId);
            jinLiUserData.setMallId(mallId);
            jinLiUserData.setLuckyNum(jinLiData.getLuckyNum());
            jinLiUserData.setAddTime(System.currentTimeMillis());
            jinLiUserData.setInsertOption();
            listMap.put(userId, jinLiUserData);
            userDataMap.put(mallId, listMap);

            // 幸运数字自增
            jinLiData.setLuckyNum(jinLiData.getLuckyNum() + 1);
            // 购买数量
            jinLiData.setTotalNum(jinLiData.getTotalNum() + 1);

            // 记录下日志
//            addLogJinLiAdd(new LogJinLiAdd(activityInfo.getActivityId(), mallId, userId, jinLiUserData.getLuckyNum()));
            CrossAutoLogMgr.add(new LogJinLiAdd(activityInfo.getActivityId(), mallId, userId, jinLiUserData.getLuckyNum()));
        }
        // 同步下用户数据
        syncUserJinLiData(serverId, userId);
    }

    /**
     * 移除锦鲤签
     */
    public void removeJinLi(List<Long> userIdList, int mallId) {
        // 有没有档位
        MallInfo mallInfo = mallInfoMap.get(mallId);
        if (mallInfo == null) {
            return;
        }
        // 随机一个幸运签,这里加个锁
        synchronized (getMallLock(mallId)) {
            CrossJinLiData jinLiData = getJinLiData(mallId);
            if (jinLiData == null) {
                return;
            }
            Map<Long, CrossJinLiUserData> listMap = userDataMap.getOrDefault(mallId, new ConcurrentHashMap<>());
            for (Long userId : userIdList) {
                CrossJinLiUserData jinLiUserData = listMap.get(userId);
                if (jinLiUserData == null || jinLiUserData.getLuckyNum() == 0) {
                    continue;
                }
                jinLiUserData.setLuckyNum(0);
                // 锦鲤购买人数-1
                jinLiData.setTotalNum(jinLiData.getTotalNum() - 1);
            }
        }
    }

    /**
     * 计算锦鲤数量
     *
     * @param mallId
     * @return
     */
    public int countJinLiNum(int mallId) {
        MallInfo mallInfo = mallInfoMap.get(mallId);
        if (mallInfo == null) {
            return 0;
        }
        CrossJinLiData jinLiData = getJinLiData(mallId);
        List<String> paramList = StringUtils.stringToStringList(mallInfo.getExtendParam(), "@");
        // 当前购买的人数
        int p2 = Integer.parseInt(paramList.get(1));
        int needDrawCnt = p2 == -1 ? 1 : (int) Math.ceil(1.0 * jinLiData.getTotalNum() / p2);
        // 保底数量
        return Math.max(Integer.parseInt(paramList.get(2)), needDrawCnt);
    }

    /**
     * 同步下用户的锦鲤数据
     *
     * @param userId 用户id
     */
    public void syncUserJinLiData(long serverId, long userId) {
        if (!ActivityHelper.activityInShowTime(activityInfo)) {
            return;
        }
        JinLiProto.JinLiDataSyncMsg.Builder syncMsg = JinLiProto.JinLiDataSyncMsg.newBuilder();
        syncMsg.setActivityId(activityInfo.getActivityId());
        // 获取我自己的锦鲤签
        List<Map<Long, CrossJinLiUserData>> userList = new ArrayList<>(userDataMap.values());
        for (Map<Long, CrossJinLiUserData> map : userList) {
            for (Map.Entry<Long, CrossJinLiUserData> entry : map.entrySet()) {
                if (entry.getKey() == userId) {
                    // 我的锦鲤签
                    JinLiProto.JinLiUserItemMsg.Builder userItem = JinLiProto.JinLiUserItemMsg.newBuilder();
                    userItem.setMallId(entry.getValue().getMallId());
                    userItem.setLuckyNum(entry.getValue().getLuckyNum());
                    syncMsg.addUserItem(userItem);
                }
            }
        }
        // 是否开过奖,有一档开过奖都当开奖了
        boolean isReward = false;
        JinLiProto.JinLiLuckyInfoMsg.Builder luckyMsg = JinLiProto.JinLiLuckyInfoMsg.newBuilder();
        // 中奖信息
        List<CrossJinLiData> jinLiList = new ArrayList<>(jinLiDataMap.values());
        for (CrossJinLiData jinLiData : jinLiList) {
            if (!jinLiData.isReward()) {
                continue;
            }
            isReward = true;
            Map<Long, CrossJinLiUserData> map = userDataMap.getOrDefault(jinLiData.getMallId(), new ConcurrentHashMap<>());
            for (CrossJinLiUserData jinLiUserData : map.values()) {
                if (jinLiData.getLuckyNumList().contains(jinLiUserData.getLuckyNum())) {
                    // 中奖者
                    UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(jinLiUserData.getUserId());
                    if (userBaseInfo == null) {
                        continue;
                    }
                    JinLiProto.JinLiLuckyItemMsg.Builder luckyItem = JinLiProto.JinLiLuckyItemMsg.newBuilder();
                    luckyItem.setMallId(jinLiUserData.getMallId());
                    luckyItem.setLuckyNum(jinLiUserData.getLuckyNum());
                    luckyItem.setUserId(jinLiUserData.getUserId());
                    luckyItem.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                    luckyMsg.addLuckyItem(luckyItem);
                }
            }
        }
        if (isReward) {
            syncMsg.setLuckyInfo(luckyMsg);
        }
        // 锦鲤数量
        for (Integer mallId : mallInfoMap.keySet()) {
            MallInfo mallInfo = mallInfoMap.get(mallId);
            if (mallInfo.getActivityId() != activityInfo.getActivityId()) {
                continue;
            }
            JinLiProto.JinLiTotalNumMsg.Builder totalNumTemp = JinLiProto.JinLiTotalNumMsg.newBuilder();
            totalNumTemp.setMallId(mallId);
            totalNumTemp.setJinLiNum(countJinLiNum(mallId));
            syncMsg.addTotalNum(totalNumTemp);
        }
        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.U_JINLI_DATA_SYNC, syncMsg));
    }

    public synchronized CrossJinLiData getJinLiData(int mallId) {
        if (!jinLiDataMap.containsKey(mallId)) {
            CrossJinLiData jinLiData = new CrossJinLiData();
            jinLiData.setActivityId(activityInfo.getActivityId());
            jinLiData.setMallId(mallId);
            MallInfo mallInfo = mallInfoMap.get(mallId);
            if (mallInfo != null) {
                // 初始的幸运数字
                List<String> paramList = StringUtils.stringToStringList(mallInfo.getExtendParam(), "@");
                jinLiData.setLuckyNum(Integer.parseInt(paramList.get(0)));
            }
            jinLiData.setLuckyNumList(new ArrayList<>());
            jinLiData.setUpdateTime(System.currentTimeMillis());
            jinLiData.setReward(false);
            jinLiData.setInsertOption();
            jinLiDataMap.put(mallId, jinLiData);
        }
        return jinLiDataMap.get(mallId);
    }

    /**
     * 抽锦鲤
     */
    public void drawJinLiTask() {
        // 到活动结束后才执行
        if (!ActivityHelper.activityInShowTime(activityInfo)) {
            return;
        }
        long nowTime = System.currentTimeMillis();
        if (nowTime / 1000 < activityInfo.getEndTime()) {
            // 活动结束后才能抽取
            return;
        }
        boolean needSync = false;
        // 开始抽锦鲤
        for (Map.Entry<Integer, MallInfo> entry : mallInfoMap.entrySet()) {
            // 锦鲤标识
            Integer mallId = entry.getKey();
            MallInfo mallInfo = mallInfoMap.get(mallId);
            if (mallInfo.getActivityId() != activityInfo.getActivityId()) {
                continue;
            }
            // 判断下有没有生成过锦鲤， 锦鲤标识
            // 加个锁
            synchronized (getMallLock(mallId)) {
                CrossJinLiData jinLiData = getJinLiData(mallId);
                if (jinLiData.isReward()) {
                    // 已发奖，跳过
                    continue;
                }
                needSync = true;
                // 保险起见，先改标识,有问题再补发
                jinLiData.setReward(true);
                // 开始发奖
                // 获取所有的幸运签
                Set<Integer> allLuckyNumSet = new HashSet<>();
                Map<Long, CrossJinLiUserData> listMap = userDataMap.getOrDefault(mallId, new ConcurrentHashMap<>());
                for (CrossJinLiUserData jinLiUserData : listMap.values()) {
                    if (jinLiUserData.getLuckyNum() != 0) {
                        allLuckyNumSet.add(jinLiUserData.getLuckyNum());
                    }
                }
                // 解析下配置
                // 锦鲤签ID最小值@锦鲤签ID最大值@锦鲤人数增加条件@返利百分比@锦鲤中奖奖励
                List<String> paramList = StringUtils.stringToStringList(entry.getValue().getExtendParam(), "@");
                // 开始抽
                List<Integer> luckyNumList = RandomHelper.getRandomList(new ArrayList<>(allLuckyNumSet), countJinLiNum(mallId));
                // 记录一下
                jinLiData.setLuckyNumList(luckyNumList);
                jinLiData.setUpdateTime(nowTime);
                // 保存下数据
                jinLiDataMap.put(mallId, jinLiData);
                // 发邮件

                // 锦鲤大奖
                String reward = PropertyHelper.parsePropertyToString(PropertyHelper.parseNewStringToProperty(paramList.get(4)));
                for (CrossJinLiUserData jinLiUserData : listMap.values()) {
                    long userId = jinLiUserData.getUserId();
                    if (jinLiData.getLuckyNumList().contains(jinLiUserData.getLuckyNum())) {
                        // 中奖了,发邮件
                        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
                        if (userBaseInfo == null) {
                            // 如果重启了服务，内存会不会拿不到用户数据？
                            continue;
                        }
                        // 发到游戏服
                        long serverId = userBaseInfo.getServerId();
                        JinLiProto.CrossSendJinLiRewardReqMsg.Builder builder = JinLiProto.CrossSendJinLiRewardReqMsg.newBuilder();
                        builder.setServerId(serverId);
                        builder.setUserId(userId);
                        builder.setMallId(jinLiUserData.getMallId());
                        builder.setLuckyNum(jinLiUserData.getLuckyNum());
                        // 锦鲤奖励
                        builder.setReward(reward);
                        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.S_JINLI_SEND_REWARD_FROM_CROSS, builder));
                    }

                }
                // 记录下日志
//                addLogJinLiLucky(new LogJinLiLucky(activityInfo.getActivityId(), mallId, jinLiData.getLuckyNumList(), reward));
                CrossAutoLogMgr.add(new LogJinLiLucky(activityInfo.getActivityId(), mallId, jinLiData.getLuckyNumList(), reward));
            }
        }
        // 广播一下
        if (needSync) {
            // 广播到各个游戏服
            JinLiProto.JinLiDataSyncMsg.Builder syncMsg = JinLiProto.JinLiDataSyncMsg.newBuilder();
            syncMsg.setActivityId(activityInfo.getActivityId());
            JinLiProto.JinLiLuckyInfoMsg.Builder luckyMsg = JinLiProto.JinLiLuckyInfoMsg.newBuilder();
            // 中奖信息
            List<CrossJinLiData> jinLiList = new ArrayList<>(jinLiDataMap.values());
            for (CrossJinLiData jinLiData : jinLiList) {
                if (!jinLiData.isReward()) {
                    continue;
                }
                Map<Long, CrossJinLiUserData> map = userDataMap.getOrDefault(jinLiData.getMallId(), new ConcurrentHashMap<>());
                for (CrossJinLiUserData jinLiUserData : map.values()) {
                    if (jinLiData.getLuckyNumList().contains(jinLiUserData.getLuckyNum())) {
                        // 中奖者
                        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(jinLiUserData.getUserId());
                        if (userBaseInfo == null) {
                            continue;
                        }
                        JinLiProto.JinLiLuckyItemMsg.Builder luckyItem = JinLiProto.JinLiLuckyItemMsg.newBuilder();
                        luckyItem.setMallId(jinLiUserData.getMallId());
                        luckyItem.setLuckyNum(jinLiUserData.getLuckyNum());
                        luckyItem.setUserId(jinLiUserData.getUserId());
                        luckyItem.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                        luckyMsg.addLuckyItem(luckyItem);
                    }
                }
            }
            syncMsg.setLuckyInfo(luckyMsg);
            // 锦鲤数量
            for (Integer mallId : mallInfoMap.keySet()) {
                MallInfo mallInfo = mallInfoMap.get(mallId);
                if (mallInfo.getActivityId() != activityInfo.getActivityId()) {
                    continue;
                }
                JinLiProto.JinLiTotalNumMsg.Builder totalNumTemp = JinLiProto.JinLiTotalNumMsg.newBuilder();
                totalNumTemp.setMallId(mallId);
                totalNumTemp.setJinLiNum(countJinLiNum(mallId));
                syncMsg.addTotalNum(totalNumTemp);
            }
            for (Long serverId : activityInfo.getServerIdList()) {
                MessageHelper.sendPacket(serverId, 0, YanQuMessageUtils.buildMessage(Protocol.S_JINLI_SYNC_DATA_FROM_CROSS, syncMsg));
            }
        }
    }
}
